package edu.ucsc.gameAI;

import java.awt.Color;
import java.util.Vector;

import pacman.game.Constants.DM;
import pacman.game.Constants.GHOST;
import pacman.game.Constants.MOVE;
import pacman.game.Game;
import pacman.game.GameView;
import edu.ucsc.gameAI.Debug.MESSAGETYPE;
import edu.ucsc.gameAI.decisionTrees.binary.IBinaryNode;

public class MoveTowardsClosestEdibleGhostAction implements IAction, IBinaryNode {

	GHOST closestGhost;
	
	public void doAction() {
		/*
		Debug.debug("MoveTowardsClosestEdibleGhostAction::DOACTION", MESSAGETYPE.ACTION);
		int pacManCurrentNode = game.getPacmanCurrentNodeIndex();
		
		Vector<GHOST> edibleGhosts = new Vector<GHOST>();
		for (GHOST ghost: GHOST.values()){
			//System.out.println("ghost " + ghost + " is currently at node " + game.getGhostCurrentNodeIndex(ghost));
			if(game.isGhostEdible(ghost)){ //If any Ghosts Are Edible
				edibleGhosts.add(ghost); // store which ghosts are edible.	
				//System.out.println("Adding " + ghost + " to vector of edible ghosts");
			}
		}
		
		//Find which edible ghost is the closest
		int closestGhostDistance = 9000;
		int closestGhostIndex = -1;
		//GHOST closestGhost = GHOST.BLINKY;
		for (GHOST edibleGhost: edibleGhosts){
			//System.out.println("Looking at ghost " + edibleGhost + " to see which is closest");
			int currentGhostIndex = game.getGhostCurrentNodeIndex(edibleGhost);
			int currentGhostDistance = game.getShortestPathDistance(pacManCurrentNode, currentGhostIndex );
			if(currentGhostDistance < closestGhostDistance){
				closestGhostDistance = currentGhostDistance;
				closestGhostIndex = currentGhostIndex;
				//closestGhost = edibleGhost;
			}
		}
		
		return game.getNextMoveTowardsTarget(pacManCurrentNode, closestGhostIndex, DM.PATH);
	*/
	}
	
	public MOVE getMove() {
		// TODO Auto-generated method stub
		return MOVE.RIGHT;
	}
	
	public MOVE getMove(Game game){
		Debug.debug("MoveTowardsClosestEdibleGhostAction::DOACTION", MESSAGETYPE.ACTION);
		int pacManCurrentNode = game.getPacmanCurrentNodeIndex();
		boolean isPowerPillInTheWay = false;
		
		Vector<GHOST> edibleGhosts = new Vector<GHOST>();
		Vector<GHOST> nonEdibleGhosts = new Vector<GHOST>();
		for (GHOST ghost: GHOST.values()){
			//System.out.println("ghost " + ghost + " is currently at node " + game.getGhostCurrentNodeIndex(ghost));
			if(game.isGhostEdible(ghost)){ //If any Ghosts Are Edible
				edibleGhosts.add(ghost); // store which ghosts are edible.	
				//System.out.println("Adding " + ghost + " to vector of edible ghosts");
			}
			else{
				nonEdibleGhosts.add(ghost);
			}
		}
		
		//Find which edible ghost is the closest
		int closestGhostDistance = Integer.MAX_VALUE;
		int closestGhostIndex = -1;
		int currentDangerGhostDistnace;
		int closestDangerGhostDistance = Integer.MAX_VALUE;
		int closestDangerGhostIndex = -1;
		int closestPowerPillIndex = game.getClosestNodeIndexFromNodeIndex(
				pacManCurrentNode, game.getActivePowerPillsIndices(), DM.PATH);
		//GHOST closestGhost = GHOST.BLINKY;
		for (GHOST edibleGhost: edibleGhosts){
			boolean safePath = true;
			//System.out.println("Looking at ghost " + edibleGhost + " to see which is closest");
			int currentGhostIndex = game.getGhostCurrentNodeIndex(edibleGhost);
			
			//Ok, sweet! We've got the closest edible ghost!
			//BUT... are there any non-edible ghosts in between him and I?
			//If so.. then.. umm.. let's leave it well enough alone!
			
			for(GHOST dangerGhost : nonEdibleGhosts){
				int[] pathToCurrentEdibleGhost = game.getShortestPath(pacManCurrentNode, currentGhostIndex);
				for(int i=0; i < pathToCurrentEdibleGhost.length; i++){
					if(pathToCurrentEdibleGhost[i] == game.getGhostCurrentNodeIndex(dangerGhost)){
						currentDangerGhostDistnace = game.getShortestPathDistance(pacManCurrentNode, game.getGhostCurrentNodeIndex(dangerGhost));
						if(currentDangerGhostDistnace < closestDangerGhostDistance){
							closestDangerGhostDistance = currentDangerGhostDistnace;
							closestDangerGhostIndex = game.getGhostCurrentNodeIndex(dangerGhost);
						}
						
						//Oh oh, the current path we want to walk on contains a ghost. That means that this path isn't so good.
						safePath = false;
					}
				}
			}
			
			if(!safePath){
				continue; // let's look at the next edible ghost -- maybe it will be safer to chase.
			}
			
			int[] pathToThisGhostIndex = game.getShortestPath(pacManCurrentNode, currentGhostIndex);
			
			// Great, now we have the shortest path, let's make sure that it
			// doesn't include a power pill.
			// AND... I think maybe we can save ourselves a little bit of
			// overhead by only caring about the power pill CLOSEST to pacman.

			for (int i = 0; i < pathToThisGhostIndex.length; i++) {
				if (pathToThisGhostIndex[i] == closestPowerPillIndex) {
					// Oh oh, there is a power pill on this path. DON'T EAT THIS
					// PILL!!!!
					isPowerPillInTheWay = true;
					break;
				}
			}
			if(isPowerPillInTheWay && closestDangerGhostDistance < 20){
				//technically I don't want to go here, because it will reset my multiplier,
				//but, you know what, there is a scary ghost close to us, so let's just
				//cut our losses and eat him.
				Debug.debug("going on a path with a power pellet, even though it will reset our multiplier. But it's because  scary ghost was chasing us.", Debug.MESSAGETYPE.STATEMENT);
			}
			/*
			else if (isPowerPillInTheWay) {
				// we aren't interested in this ghost because pacman would have
				// to eat a power pellet to reach him. let's move on to the next ghost.
				// Maybe in the future we could do something smarter, like
				// finding an alternative path.
				Debug.debug("POWER PILL INBETWEEN ME AND GHOSTS. IGNORING GHOST", Debug.MESSAGETYPE.ACTION);
				continue;
			}
			*/
			
			int currentGhostDistance = game.getShortestPathDistance(pacManCurrentNode, currentGhostIndex );
			if(currentGhostDistance < closestGhostDistance){
				closestGhostDistance = currentGhostDistance;
				closestGhostIndex = currentGhostIndex;
				//closestGhost = edibleGhost;
			}
		}
		if(closestGhostIndex == -1){
			//There were no safe ghosts to chase! Probably in real life want to 
			//bump this out into a condition and transition into a separate state.
			//There is a chance that we might get here but we haven't officialy set 'closestDangerGhost (because of powerPill avoidance)
			//If that is the case, then we are just going to move away from one of the ghosts, the default value of closestDangerGhostIndex.
			Debug.debug("WANT TO EAT GHOSTS BUT NO SAFE PATHS. UM, FOR NOW, PANIC!!", Debug.MESSAGETYPE.ACTION);
			if(closestDangerGhostIndex == -1){
				//we didn't find any dangerous ghosts, but power pills block the ghosts I want to eat...
				//I guess just... move away from the closest power pill?
				//This, sadly, does result in some waffling.
				Debug.debug("Don't want to reset the multiplier--I'm OUTTA here!", Debug.MESSAGETYPE.ACTION);
				return game.getNextMoveAwayFromTarget(pacManCurrentNode, closestPowerPillIndex, DM.PATH);
				//closestDangerGhostIndex = 1;
			}
			return new RunAwayFromGhosts().getMove(game);
		}
		
		int[] edibleGhostPath = game.getShortestPath(pacManCurrentNode, closestGhostIndex);
		GameView.addPoints(game, Color.BLUE, edibleGhostPath );
		GameView.addPoints(game, Color.RED, closestGhostIndex);
		return game.getNextMoveTowardsTarget(pacManCurrentNode, closestGhostIndex, DM.PATH);
	
	}
	
	public IAction makeDecision(Game game) {return this;}
}
